/*
 * Copyright (C) 2008 Peter Kling
 * 
 * This file is part of 'A Kind of Billiard', a graphical billiard simulation.
 * 
 * 'A Kind of Billiard' is free software: you can redistribute it and/or modify it under the terms of the GNU General
 * Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
 * later version.
 * 
 * 'A Kind of Billiard' is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with 'A Kind of Billiard'. If not, see
 * <http://www.gnu.org/licenses/>.
 */

package de.akob.physics;

import de.akob.mathematics.MathMatrix;
import de.akob.mathematics.Mathematics;

/**
 * A physical object modeling a ball. In contrast to standard physical object, balls keep track of their orientation.
 * Therefore they store rotational information as angles around the three axis. Note: currently there it is always
 * assumed that balls role in the (x,z)-plane, so the angle for the y-axis is always zero.
 */
public class PhysicalBall extends PhysicalObject {
	protected double     radius;
	protected MathMatrix orientation = new MathMatrix(4, 4);
	
	/**
	 * Constructs a billiard ball.
	 */
	public PhysicalBall(double mass, double radius) {
		super(mass);
		this.radius = radius;
		orientation = Mathematics.getUnitMatrix(4);
	}
	//	
	// /**
	// * Returns a 4x4 matrix that represents the orientation of this object. The matrix is a simple rotational matrix.
	// We
	// * use a 4x4 matrix for easy interaction with the OpenGL state matrices.
	// */
	// public MathMatrix getOrientation() {
	// return orientation.clone();
	// }
	//	
	// /**
	// * Returns the radius.
	// */
	// public double getRadius() {
	// return radius;
	// }
	//	
	// /**
	// * In addition to the motion aspects of normal physical aspects, balls keep track of their orientation.
	// * <p>
	// * Note: Currently they do so only for movements in the (x,z)-plane.
	// */
	// @Override
	// public void update() {
	// MathVector oldPosition = position.clone();
	// super.update();
	// MathVector positionDifference = Mathematics.sub(position, oldPosition);
	//		
	// // update orientation only for movements on the ground obstacle (currently this is done for all (x,z)-planes;
	// // we check for movements in such planes with a tolerance of about 11.5 degree; the y-parts of movements with
	// // smaller angles are neglected for orientation)
	// // TODO: this is not very elegant/robust --> improve
	// MathVector normal = Mathematics.getUnitVector(3, 2);
	// if (Math.abs(Mathematics.mul(normal, positionDifference) / positionDifference.norm()) > 2.E-1)
	// return;
	// positionDifference.set(2, 0.);
	//		
	// // check if we moved (if not, we do not need to update the orientation)
	// if (positionDifference.norm() == 0.)
	// return;
	//		
	// // update orientation of the ball
	// double alpha = positionDifference.norm() / radius;
	//		
	// // cross product with (0, -1, 0) to get axis for rotation
	// MathVector axis = new MathVector(3);
	// axis.set(1, positionDifference.get(3));
	// axis.set(2, 0.);
	// axis.set(3, -positionDifference.get(1));
	//		
	// // update orientation matrix
	// orientation = Mathematics.mul(Mathematics.getRotationMatrix3D_hom(alpha, axis), orientation);
	// }
}
